Handhaving heeft de grootste invloed op misdaad#

Uitleg van perspectief + argumenten uit andere bronnen, redenering…

Met strengere straffen op illegale activiteiten worden deze minder aantrekkelijk voor potentiële misdadigers. Door de kans om gepakt te worden te vergroten en de gevolgen zwaarder te maken kan een land er voor zorgen dat de mogelijke winsten van misdaad de risico’s niet langer waard zijn, en mensen in plaats hiervan voor legale wegen kiezen om hun lot te verbeteren.

Volgens Petersen et al. (2023) zorgen willekeurige voetgangersstops door politie voor een 11% mindering in misdaad. Door deze stops worden misdaden tegengehouden voordat ze gebeuren en zijn mensen minder geneigd om misdaden te plegen. Meer politie agenten betekent dat dit soort interventies meer kunnen plaatsvinden, wat uiteindelijke misdaadcijfers helpt te bedwingen.

Armere landen ervaren minder misdaden doordat er meer politie agenten zijn#

In figuur 4 is een algemeen positieve trend te zien tussen GDP per capita en de totale criminele activiteit. Dit lijkt te suggereren dat rijke landen meer te kampen hebben met illegale activiteiten dan minder welvarende.

Hide code cell source
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import plotly.io as pio

pio.renderers.default = 'notebook'

# Load and process data
diefstallenbank1_df = pd.read_csv("world_bank_definitive.csv")
crime_df = pd.read_csv("europe_crime_definitive_per_100k.csv")

bank_df = diefstallenbank1_df[diefstallenbank1_df['Indicator Name'] == "GDP per capita, PPP (constant 2021 international $)"]
bank_df = bank_df.rename(columns={"Value": "GDP per capita, PPP (constant 2021 international $)"})

crime_columns = [col for col in crime_df.columns if col not in ["Country Name", "Year", "geo"]]
crime_df["Total Crime Rate per 100k"] = crime_df[crime_columns].sum(axis=1)

merged_df = pd.merge(
    crime_df[["Country Name", "Year", "Total Crime Rate per 100k"]],
    bank_df[["Country Name", "Year", "GDP per capita, PPP (constant 2021 international $)"]],
    on=["Country Name", "Year"]
)

# Prepare data for polynomial fit
x = merged_df["GDP per capita, PPP (constant 2021 international $)"]
y = merged_df["Total Crime Rate per 100k"]


# Drop rows with missing or infinite values
filtered_df = merged_df.replace([np.inf, -np.inf], np.nan).dropna(subset=[
    "GDP per capita, PPP (constant 2021 international $)", "Total Crime Rate per 100k"
])

x = filtered_df["GDP per capita, PPP (constant 2021 international $)"]
y = filtered_df["Total Crime Rate per 100k"]
# Fit a 2nd-degree polynomial (quadratic curve)
degree = 2  # you can change this to 3 for a cubic fit
coeffs = np.polyfit(x, y, deg=degree)
poly_func = np.poly1d(coeffs)

# Create x values for the trendline
x_vals = np.linspace(x.min(), x.max(), 500)
y_vals = poly_func(x_vals)

# Plot scatter with curved trendline
fig = px.scatter(
    merged_df,
    x="GDP per capita, PPP (constant 2021 international $)",
    y="Total Crime Rate per 100k",
    hover_name="Country Name",
    hover_data={"Year": True},
    title="GDP per Capita vs. Total Crime Rate per 100k with Curved Trendline"
)

# Add polynomial curve
fig.add_trace(go.Scatter(
    x=x_vals,
    y=y_vals,
    mode='lines',
    name=f'Polynomial Trendline (deg={degree})',
    line=dict(color='red', dash='dash')
))

fig.update_layout(
    xaxis_title="GDP per capita, PPP (constant 2021 international $)",
    yaxis_title="Total Crime Rate per 100k",
    showlegend=False
)


fig.show()

Figuur 4: Het GDP per capita, PPP in 2021 dollars vs het totaal aantal misdaden per land. Elk land is voor elk jaar dat het voorkomt in onze dataset weergegeven. Er is een posiieve correlatie te zien tussen het GDP per capta en criminaliteit tussen 0 en 60.000 dollar. Hierna is er ongeveer een negaatieve correlatie te zien.

Meer agenten, minder misdaad#

In figuur 5 zien we dat er een correlatie is tussen het aantal politieagenten en het aantal misdaden zoals perspectief 2 voorspelt. Op het eerste gezicht ziet het er inderdaad uit alsof een groter aantal politieagenten zorgt voor minder misdaad. Dit zou het perspectief steunen dat strengere handhaving zorgt voor minder criminaliteit.

Het is belangrijk om op te merken dat in deze visualisatie geen rekening wordt gehouden met andere variabelen die mogelijk invloed hebben op de vertoonde correlatie, zoals vertrouwen in de politie en rechtsstaat, corruptie binnen de politie en de strategie waarmee politie wordt ingezet.

Hide code cell source
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
import plotly.io as pio

pio.renderers.default = 'notebook'

# Load and process data
police_df = pd.read_csv("europe_justice_per_100k.csv")
crime_df = pd.read_csv("europe_crime_definitive_per_100k.csv")


crime_columns = [col for col in crime_df.columns if col not in ["Country Name", "Year", "geo"]]
crime_df["Total Crime Rate per 100k"] = crime_df[crime_columns].sum(axis=1)

merged_df = pd.merge(
    crime_df[["Country Name", "Year", "Total Crime Rate per 100k"]],
    police_df[["Country Name", "Year", "Police officers"]],
    on=["Country Name", "Year"]
)

# Prepare data for polynomial fit
x = merged_df["Police officers"]
y = merged_df["Total Crime Rate per 100k"]


# Drop rows with missing or infinite values
filtered_df = merged_df.replace([np.inf, -np.inf], np.nan).dropna(subset=[
    "Police officers", "Total Crime Rate per 100k"
])

x = filtered_df["Police officers"]
y = filtered_df["Total Crime Rate per 100k"]
# Fit a 2nd-degree polynomial (quadratic curve)
degree = 2  # you can change this to 3 for a cubic fit
coeffs = np.polyfit(x, y, deg=degree)
poly_func = np.poly1d(coeffs)

# Create x values for the trendline
x_vals = np.linspace(x.min(), x.max(), 500)
y_vals = poly_func(x_vals)

# Plot scatter with curved trendline
fig = px.scatter(
    merged_df,
    x="Police officers",
    y="Total Crime Rate per 100k",
    hover_name="Country Name",
    hover_data={"Year": True},
    title="Police officers vs. Total Crime Rate per 100k with Curved Trendline"
)

# Add polynomial curve
fig.add_trace(go.Scatter(
    x=x_vals,
    y=y_vals,
    mode='lines',
    name=f'Polynomial Trendline (deg={degree})',
    line=dict(color='red', dash='dash')
))

fig.update_layout(
    xaxis_title="Police officers",
    yaxis_title="Total Crime Rate per 100k",
    showlegend=False
)


fig.show()

Figuur 5: Totale aantal misdaden per 100.000 inwoners is afgezet tegen het aantal politieagenten per 100.000 inwoners. Uit deze figuur blijkt dat over het algemeen geldt dat hoe meer politieagenten er zijn, hoe minder misdaden worden gerapporteerd.

Argument 3: Meer politie in landen met lager GDP per capita#

Hoewel je zou verwachten dat armere landen minder geld hebben voor meer politie agenten, is dit niet altijd het geval. Omdat in arme landen eerder incentief kan onstaan om misdaden te plegen, kan het een goede preventieve maatregeling zijn om meer politie agenten in te schakelen. In deze grafiek zie je dat als onze data in vier gelijke delen opdeelt, dat er een trend in Europa is dat hoe hoger het GDP per capita is, hoe lager het aantal politieagenten per 100.000 inwoners is.

Hier zijn natuurlijk uitzonderingen op en het moet opgemerkt worden dat dit ook zou kunnen komen doordat specifieke landen een ander politiek beleid hebben waardoor er meer politie is (wat niet perse met welvaart te maken heeft). Maar dit geeft wel een mogelijke uitleg voor waarom er in armere landen minder misdaden plaatsvinden: namelijk dat er meer politie is om misdaden tegen te houden/af te schrikken. Je zou dus kunnen zeggen dat er minder misdaden in armere landen plaatsvinden tegenover rijkere landen, doordat armere landen meer politie hebben en door die politie onstaat minder misdaad.

Hide code cell source
import pandas as pd
import plotly.express as px
import plotly.io as pio

pio.renderers.default = 'notebook'

# Load data
bank1_df = pd.read_csv("world_bank_definitive.csv")
police_df = pd.read_csv("europe_justice_per_100k.csv")

# Filter GDP data
bank_df = bank1_df[bank1_df['Indicator Name'] == "GDP per capita, PPP (constant 2021 international $)"]
bank_df = bank_df.rename(columns={"Value": "GDP per capita, PPP (constant 2021 international $)"})

# Merge datasets
merged_df = pd.merge(
    police_df[["Country Name", "Year", "Police officers"]],
    bank_df[["Country Name", "Year", "GDP per capita, PPP (constant 2021 international $)"]],
    on=["Country Name", "Year"]
)

# Drop missing values
merged_df = merged_df.dropna()

# Compute quartiles with actual bin edges
gdp_series = merged_df["GDP per capita, PPP (constant 2021 international $)"]
quartiles, bins = pd.qcut(gdp_series, q=4, retbins=True, precision=0)

# Format bin labels with ranges
quartile_labels = [
    f"Q1: {int(bins[0]):,}{int(bins[1]):,}",
    f"Q2: {int(bins[1]+1):,}{int(bins[2]):,}",
    f"Q3: {int(bins[2]+1):,}{int(bins[3]):,}",
    f"Q4: {int(bins[3]+1):,}{int(bins[4]):,}"
]

# Assign quartile labels
merged_df['GDP Quartile'] = pd.qcut(
    gdp_series,
    q=4,
    labels=quartile_labels
)

# Define blue gradient colors
color_discrete_map = {
    quartile_labels[0]: "#03DBFC",  # Light blue
    quartile_labels[1]: "#00B4FF",
    quartile_labels[2]: "#006CFF",
    quartile_labels[3]: "#000FFF"   # Dark blue
}

# Create box plot with custom colors and ordered x-axis
fig = px.box(
    merged_df,
    x="GDP Quartile",
    y="Police officers",
    color="GDP Quartile",
    color_discrete_map=color_discrete_map,
    category_orders={"GDP Quartile": quartile_labels},
    title="Police Officers per 100k by GDP per Capita, for each quartile of the data",
    labels={"Police officers": "Police Officers per 100k", "GDP Quartile": "GDP per Capita Quartile"}
)

# Update layout to remove legend (since the x-axis already shows quartiles)
fig.update_layout(showlegend=False)

fig.show()